#include "wx/wxprec.h"
#include "wx/datetime.h"
#include "wx/print.h"
#include "wx/printdlg.h"
#include "wx/richtext/richtextprint.h"
#include "wx/wfstream.h"

wxRichTextPrintout::wxRichTextPrintout( const wxString& title ) : wxPrintout( title ) {
  m_numPages = wxRICHTEXT_PRINT_MAX_PAGES;
  SetMargins(); // to default values
}

wxRichTextPrintout::~wxRichTextPrintout() {
}

void wxRichTextPrintout::OnPreparePrinting() {
  wxBusyCursor wait;
  m_numPages = 1;
  m_pageBreaksStart.Clear();
  m_pageBreaksEnd.Clear();
  int lastStartPos = 0;
  wxRect rect, headerRect, footerRect;
  /// Sets the DC scaling and returns important page rectangles
  CalculateScaling( GetDC(), rect, headerRect, footerRect );
  if( GetRichTextBuffer() ) {
    GetRichTextBuffer()->Invalidate( wxRICHTEXT_ALL );
    GetRichTextBuffer()->Layout( *GetDC(), rect, wxRICHTEXT_FIXED_WIDTH | wxRICHTEXT_VARIABLE_HEIGHT );
    // Now calculate the page breaks
    int yOffset = 0;
    wxRichTextLine* lastLine = NULL;
    wxRichTextObjectList::compatibility_iterator node = GetRichTextBuffer()->GetChildren().GetFirst();
    while( node ) {
      // child is a paragraph
      wxRichTextParagraph* child = wxDynamicCast( node->GetData(), wxRichTextParagraph );
      wxASSERT( child != NULL );
      wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst();
      while( node2 ) {
        wxRichTextLine* line = node2->GetData();
        // Set the line to the page-adjusted position
        line->SetPosition( wxPoint( line->GetPosition().x, line->GetPosition().y - yOffset ) );
        int lineY = child->GetPosition().y + line->GetPosition().y;
        // Break the page if either we're going off the bottom, or this paragraph specifies
        // an explicit page break
        if( ( ( lineY + line->GetSize().y ) > rect.GetBottom() ) ||
            ( ( node2 == child->GetLines().GetFirst() ) && child->GetAttributes().HasPageBreak() ) ) {
          // New page starting at this line
          int newY = rect.y;
          // We increase the offset by the difference between new and old positions
          int increaseOffsetBy = lineY - newY;
          yOffset += increaseOffsetBy;
          line->SetPosition( wxPoint( line->GetPosition().x, newY - child->GetPosition().y ) );
          if( !lastLine ) {
            lastLine = line;
          }
          m_pageBreaksStart.Add( lastStartPos );
          m_pageBreaksEnd.Add( lastLine->GetAbsoluteRange().GetEnd() );
          lastStartPos = line->GetAbsoluteRange().GetStart();
          m_numPages ++;
        }
        lastLine = line;
        node2 = node2->GetNext();
      }
      node = node->GetNext();
    }
    // Closing page break
    if( m_pageBreaksStart.GetCount() == 0 || ( m_pageBreaksEnd[m_pageBreaksEnd.GetCount() - 1] < ( GetRichTextBuffer()->GetRange().GetEnd() - 1 ) ) ) {
      m_pageBreaksStart.Add( lastStartPos );
      m_pageBreaksEnd.Add( GetRichTextBuffer()->GetRange().GetEnd() );
    }
  }
}

bool wxRichTextPrintout::OnBeginDocument( int startPage, int endPage ) {
  if( !wxPrintout::OnBeginDocument( startPage, endPage ) ) {
    return false;
  }
  return true;
}

bool wxRichTextPrintout::OnPrintPage( int page ) {
  wxDC *dc = GetDC();
  if( dc ) {
    if( HasPage( page ) ) {
      RenderPage( dc, page );
    }
    return true;
  } else
  { return false; }
}

void wxRichTextPrintout::GetPageInfo( int *minPage, int *maxPage, int *selPageFrom, int *selPageTo ) {
  *minPage = 1;
  *maxPage = m_numPages;
  *selPageFrom = 1;
  *selPageTo = m_numPages;
}

bool wxRichTextPrintout::HasPage( int pageNum ) {
  return pageNum > 0 && pageNum <= m_numPages;
}

void wxRichTextPrintout::RenderPage( wxDC *dc, int page ) {
  if( !GetRichTextBuffer() ) {
    return;
  }
  wxBusyCursor wait;
  wxRect textRect, headerRect, footerRect;
  /// Sets the DC scaling and returns important page rectangles
  CalculateScaling( dc, textRect, headerRect, footerRect );
  if( page > 1 || m_headerFooterData.GetShowOnFirstPage() ) {
    if( m_headerFooterData.GetFont().Ok() ) {
      dc->SetFont( m_headerFooterData.GetFont() );
    } else
    { dc->SetFont( *wxNORMAL_FONT ); }
    if( m_headerFooterData.GetTextColour().Ok() ) {
      dc->SetTextForeground( m_headerFooterData.GetTextColour() );
    } else
    { dc->SetTextForeground( *wxBLACK ); }
    dc->SetBackgroundMode( wxTRANSPARENT );
    // Draw header, if any
    wxRichTextOddEvenPage oddEven = ( ( page % 2 ) == 1 ) ? wxRICHTEXT_PAGE_ODD : wxRICHTEXT_PAGE_EVEN;
    wxString headerTextCentre = m_headerFooterData.GetHeaderText( oddEven, wxRICHTEXT_PAGE_CENTRE );
    wxString headerTextLeft = m_headerFooterData.GetHeaderText( oddEven, wxRICHTEXT_PAGE_LEFT );
    wxString headerTextRight = m_headerFooterData.GetHeaderText( oddEven, wxRICHTEXT_PAGE_RIGHT );
    if( !headerTextLeft.IsEmpty() ) {
      SubstituteKeywords( headerTextLeft, GetTitle(), page, m_numPages );
      //int tx, ty;
      //dc->GetTextExtent(headerTextLeft, & tx, & ty);
      int x = headerRect.GetLeft();
      int y = headerRect.GetX();
      dc->DrawText( headerTextLeft, x, y );
    }
    if( !headerTextCentre.IsEmpty() ) {
      SubstituteKeywords( headerTextCentre, GetTitle(), page, m_numPages );
      int tx, ty;
      dc->GetTextExtent( headerTextCentre, & tx, & ty );
      int x = headerRect.GetWidth() / 2 - tx / 2 + headerRect.GetLeft();
      int y = headerRect.GetY();
      dc->DrawText( headerTextCentre, x, y );
    }
    if( !headerTextRight.IsEmpty() ) {
      SubstituteKeywords( headerTextRight, GetTitle(), page, m_numPages );
      int tx, ty;
      dc->GetTextExtent( headerTextRight, & tx, & ty );
      int x = headerRect.GetRight() - tx;
      int y = headerRect.GetY();
      dc->DrawText( headerTextRight, x, y );
    }
    // Draw footer, if any
    wxString footerTextCentre = m_headerFooterData.GetFooterText( oddEven, wxRICHTEXT_PAGE_CENTRE );
    wxString footerTextLeft = m_headerFooterData.GetFooterText( oddEven, wxRICHTEXT_PAGE_LEFT );
    wxString footerTextRight = m_headerFooterData.GetFooterText( oddEven, wxRICHTEXT_PAGE_RIGHT );
    if( !footerTextLeft.IsEmpty() ) {
      SubstituteKeywords( footerTextLeft, GetTitle(), page, m_numPages );
      int tx, ty;
      dc->GetTextExtent( footerTextLeft, & tx, & ty );
      int x = footerRect.GetLeft();
      int y = footerRect.GetBottom() - ty;
      dc->DrawText( footerTextLeft, x, y );
    }
    if( !footerTextCentre.IsEmpty() ) {
      SubstituteKeywords( footerTextCentre, GetTitle(), page, m_numPages );
      int tx, ty;
      dc->GetTextExtent( footerTextCentre, & tx, & ty );
      int x = footerRect.GetWidth() / 2 - tx / 2 + footerRect.GetLeft();
      int y = footerRect.GetBottom() - ty;
      dc->DrawText( footerTextCentre, x, y );
    }
    if( !footerTextRight.IsEmpty() ) {
      SubstituteKeywords( footerTextRight, GetTitle(), page, m_numPages );
      int tx, ty;
      dc->GetTextExtent( footerTextRight, & tx, & ty );
      int x = footerRect.GetRight() - tx;
      int y = footerRect.GetBottom() - ty;
      dc->DrawText( footerTextRight, x, y );
    }
  }
  wxRichTextRange rangeToDraw( m_pageBreaksStart[page - 1], m_pageBreaksEnd[page - 1] );
  GetRichTextBuffer()->Draw( *dc, rangeToDraw, wxRichTextRange( -1, -1 ), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE /* flags */ );
}

void wxRichTextPrintout::SetMargins( int top, int bottom, int left, int right ) {
  m_marginTop = top;
  m_marginBottom = bottom;
  m_marginLeft = left;
  m_marginRight = right;
}

/// Calculate scaling and rectangles, setting the device context scaling
void wxRichTextPrintout::CalculateScaling( wxDC* dc, wxRect& textRect, wxRect& headerRect, wxRect& footerRect ) {
  // Get the logical pixels per inch of screen and printer
  int ppiScreenX, ppiScreenY;
  GetPPIScreen( &ppiScreenX, &ppiScreenY );
  int ppiPrinterX, ppiPrinterY;
  GetPPIPrinter( &ppiPrinterX, &ppiPrinterY );
  // This scales the DC so that the printout roughly represents the
  // the screen scaling.
  float scale = ( float )( ( float )ppiPrinterX / ( float )ppiScreenX );
  // Now we have to check in case our real page size is reduced
  // (e.g. because we're drawing to a print preview memory DC)
  int pageWidth, pageHeight;
  int w, h;
  dc->GetSize( &w, &h );
  GetPageSizePixels( &pageWidth, &pageHeight );
  // If printer pageWidth == current DC width, then this doesn't
  // change. But w might be the preview bitmap width, so scale down.
  float previewScale = ( float )( w / ( float )pageWidth );
  float overallScale = scale * previewScale;
  // The dimensions used for indentation etc. have to be unscaled
  // during printing to be correct when scaling is applied.
  if( !IsPreview() ) {
    m_richTextBuffer->SetScale( scale );
  }
  // Calculate margins
  int marginLeft = wxRichTextObject::ConvertTenthsMMToPixels( ppiPrinterX, m_marginLeft );
  int marginTop = wxRichTextObject::ConvertTenthsMMToPixels( ppiPrinterX, m_marginTop );
  int marginRight = wxRichTextObject::ConvertTenthsMMToPixels( ppiPrinterX, m_marginRight );
  int marginBottom = wxRichTextObject::ConvertTenthsMMToPixels( ppiPrinterX, m_marginBottom );
  // Header and footer margins
  int headerMargin = wxRichTextObject::ConvertTenthsMMToPixels( ppiPrinterX, m_headerFooterData.GetHeaderMargin() );
  int footerMargin = wxRichTextObject::ConvertTenthsMMToPixels( ppiPrinterX, m_headerFooterData.GetFooterMargin() );
  dc->SetUserScale( overallScale, overallScale );
  wxRect rect( ( int )( marginLeft / scale ), ( int )( marginTop / scale ),
               ( int )( ( pageWidth - marginLeft - marginRight ) / scale ), ( int )( ( pageHeight - marginTop - marginBottom ) / scale ) );
  headerRect = wxRect( 0, 0, 0, 0 );
  if( !m_headerFooterData.GetHeaderText( wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT ).IsEmpty() ||
      !m_headerFooterData.GetHeaderText( wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE ).IsEmpty() ||
      !m_headerFooterData.GetHeaderText( wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT ).IsEmpty() ||
      !m_headerFooterData.GetHeaderText( wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT ).IsEmpty() ||
      !m_headerFooterData.GetHeaderText( wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE ).IsEmpty() ||
      !m_headerFooterData.GetHeaderText( wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT ).IsEmpty() ) {
    if( m_headerFooterData.GetFont().Ok() ) {
      dc->SetFont( m_headerFooterData.GetFont() );
    } else
    { dc->SetFont( *wxNORMAL_FONT ); }
    int charHeight = dc->GetCharHeight();
    int headerHeight = ( int )( charHeight + headerMargin / scale );
    headerRect = wxRect( rect.x, rect.y, rect.width, headerHeight );
    rect.y += headerHeight;
    rect.height -= headerHeight;
  }
  footerRect = wxRect( 0, 0, 0, 0 );
  if( !m_headerFooterData.GetFooterText( wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT ).IsEmpty() ||
      !m_headerFooterData.GetFooterText( wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE ).IsEmpty() ||
      !m_headerFooterData.GetFooterText( wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT ).IsEmpty() ||
      !m_headerFooterData.GetFooterText( wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT ).IsEmpty() ||
      !m_headerFooterData.GetFooterText( wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE ).IsEmpty() ||
      !m_headerFooterData.GetFooterText( wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT ).IsEmpty() ) {
    if( m_headerFooterData.GetFont().Ok() ) {
      dc->SetFont( m_headerFooterData.GetFont() );
    } else
    { dc->SetFont( *wxNORMAL_FONT ); }
    int charHeight = dc->GetCharHeight();
    int footerHeight = ( int )( charHeight + footerMargin / scale );
    footerRect = wxRect( rect.x, rect.y + rect.height, rect.width, footerHeight );
    rect.height -= footerHeight;
  }
  textRect = rect;
}

bool wxRichTextPrintout::SubstituteKeywords( wxString& str, const wxString& title, int pageNum, int pageCount ) {
  wxString num;
  num.Printf( wxT( "%i" ), pageNum );
  str.Replace( wxT( "@PAGENUM@" ), num );
  num.Printf( wxT( "%lu" ), ( unsigned long ) pageCount );
  str.Replace( wxT( "@PAGESCNT@" ), num );
  wxDateTime now = wxDateTime::Now();
  str.Replace( wxT( "@DATE@" ), now.FormatDate() );
  str.Replace( wxT( "@TIME@" ), now.FormatTime() );
  str.Replace( wxT( "@TITLE@" ), title );
  return true;
}

/*!
  wxRichTextPrinting
*/

wxRichTextPrinting::wxRichTextPrinting( const wxString& name, wxWindow *parentWindow ) {
  m_richTextBufferPrinting = NULL;
  m_richTextBufferPreview = NULL;
  m_parentWindow = parentWindow;
  m_title = name;
  m_printData = NULL;
  m_previewRect = wxRect( wxPoint( 100, 100 ), wxSize( 800, 800 ) );
  m_pageSetupData = new wxPageSetupDialogData;
  m_pageSetupData->EnableMargins( true );
  m_pageSetupData->SetMarginTopLeft( wxPoint( 25, 25 ) );
  m_pageSetupData->SetMarginBottomRight( wxPoint( 25, 25 ) );
}

wxRichTextPrinting::~wxRichTextPrinting() {
  delete m_printData;
  delete m_pageSetupData;
  delete m_richTextBufferPrinting;
  delete m_richTextBufferPreview;
}

wxPrintData *wxRichTextPrinting::GetPrintData() {
  if( m_printData == NULL ) {
    m_printData = new wxPrintData();
  }
  return m_printData;
}

/// Set print and page setup data
void wxRichTextPrinting::SetPrintData( const wxPrintData& printData ) {
  ( *GetPrintData() ) = printData;
}

void wxRichTextPrinting::SetPageSetupData( const wxPageSetupData& pageSetupData ) {
  ( *GetPageSetupData() ) = pageSetupData;
}

/// Set the rich text buffer pointer, deleting the existing object if present
void wxRichTextPrinting::SetRichTextBufferPrinting( wxRichTextBuffer* buf ) {
  if( m_richTextBufferPrinting ) {
    delete m_richTextBufferPrinting;
    m_richTextBufferPrinting = NULL;
  }
  m_richTextBufferPrinting = buf;
}

void wxRichTextPrinting::SetRichTextBufferPreview( wxRichTextBuffer* buf ) {
  if( m_richTextBufferPreview ) {
    delete m_richTextBufferPreview;
    m_richTextBufferPreview = NULL;
  }
  m_richTextBufferPreview = buf;
}

bool wxRichTextPrinting::PreviewFile( const wxString& richTextFile ) {
  SetRichTextBufferPreview( new wxRichTextBuffer );
  if( !m_richTextBufferPreview->LoadFile( richTextFile ) ) {
    SetRichTextBufferPreview( NULL );
    return false;
  } else
  { SetRichTextBufferPrinting( new wxRichTextBuffer( *m_richTextBufferPreview ) ); }
  wxRichTextPrintout *p1 = CreatePrintout();
  p1->SetRichTextBuffer( m_richTextBufferPreview );
  wxRichTextPrintout *p2 = CreatePrintout();
  p2->SetRichTextBuffer( m_richTextBufferPrinting );
  return DoPreview( p1, p2 );
}

bool wxRichTextPrinting::PreviewBuffer( const wxRichTextBuffer& buffer ) {
  SetRichTextBufferPreview( new wxRichTextBuffer( buffer ) );
  SetRichTextBufferPrinting( new wxRichTextBuffer( buffer ) );
  wxRichTextPrintout *p1 = CreatePrintout();
  p1->SetRichTextBuffer( m_richTextBufferPreview );
  wxRichTextPrintout *p2 = CreatePrintout();
  p2->SetRichTextBuffer( m_richTextBufferPrinting );
  return DoPreview( p1, p2 );
}

bool wxRichTextPrinting::PrintFile( const wxString& richTextFile ) {
  SetRichTextBufferPrinting( new wxRichTextBuffer );
  if( !m_richTextBufferPrinting->LoadFile( richTextFile ) ) {
    SetRichTextBufferPrinting( NULL );
    return false;
  }
  wxRichTextPrintout *p = CreatePrintout();
  p->SetRichTextBuffer( m_richTextBufferPrinting );
  bool ret = DoPrint( p );
  delete p;
  return ret;
}

bool wxRichTextPrinting::PrintBuffer( const wxRichTextBuffer& buffer ) {
  SetRichTextBufferPrinting( new wxRichTextBuffer( buffer ) );
  wxRichTextPrintout *p = CreatePrintout();
  p->SetRichTextBuffer( m_richTextBufferPrinting );
  bool ret = DoPrint( p );
  delete p;
  return ret;
}

bool wxRichTextPrinting::DoPreview( wxRichTextPrintout *printout1, wxRichTextPrintout *printout2 ) {
  // Pass two printout objects: for preview, and possible printing.
  wxPrintDialogData printDialogData( *GetPrintData() );
  wxPrintPreview *preview = new wxPrintPreview( printout1, printout2, &printDialogData );
  if( !preview->Ok() ) {
    delete preview;
    return false;
  }
  wxPreviewFrame *frame = new wxPreviewFrame( preview, m_parentWindow,
      m_title + _( " Preview" ),
      m_previewRect.GetPosition(), m_previewRect.GetSize() );
  frame->Centre( wxBOTH );
  frame->Initialize();
  frame->Show( true );
  return true;
}

bool wxRichTextPrinting::DoPrint( wxRichTextPrintout *printout ) {
  wxPrintDialogData printDialogData( *GetPrintData() );
  wxPrinter printer( &printDialogData );
  if( !printer.Print( m_parentWindow, printout, true ) ) {
    return false;
  }
  ( *GetPrintData() ) = printer.GetPrintDialogData().GetPrintData();
  return true;
}

void wxRichTextPrinting::PageSetup() {
  if( !GetPrintData()->Ok() ) {
    wxLogError( _( "There was a problem during page setup: you may need to set a default printer." ) );
    return;
  }
  m_pageSetupData->SetPrintData( *GetPrintData() );
  wxPageSetupDialog pageSetupDialog( m_parentWindow, m_pageSetupData );
  if( pageSetupDialog.ShowModal() == wxID_OK ) {
    ( *GetPrintData() ) = pageSetupDialog.GetPageSetupData().GetPrintData();
    ( *m_pageSetupData ) = pageSetupDialog.GetPageSetupData();
  }
}

wxRichTextPrintout *wxRichTextPrinting::CreatePrintout() {
  wxRichTextPrintout *p = new wxRichTextPrintout( m_title );
  p->SetHeaderFooterData( GetHeaderFooterData() );
  p->SetMargins( 10 * m_pageSetupData->GetMarginTopLeft().y,
                 10 * m_pageSetupData->GetMarginBottomRight().y,
                 10 * m_pageSetupData->GetMarginTopLeft().x,
                 10 * m_pageSetupData->GetMarginBottomRight().x );
  return p;
}

void wxRichTextPrinting::SetHeaderText( const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location ) {
  m_headerFooterData.SetHeaderText( text, page, location );
}

wxString wxRichTextPrinting::GetHeaderText( wxRichTextOddEvenPage page, wxRichTextPageLocation location ) const {
  return m_headerFooterData.GetHeaderText( page, location );
}

void wxRichTextPrinting::SetFooterText( const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location ) {
  m_headerFooterData.SetFooterText( text, page, location );
}

wxString wxRichTextPrinting::GetFooterText( wxRichTextOddEvenPage page, wxRichTextPageLocation location ) const {
  return m_headerFooterData.GetFooterText( page, location );
}

IMPLEMENT_CLASS( wxRichTextHeaderFooterData, wxObject )

void wxRichTextHeaderFooterData::Copy( const wxRichTextHeaderFooterData& data ) {
  int i;
  for( i = 0; i < 12; i++ ) {
    m_text[i] = data.m_text[i];
  }
  m_font = data.m_font;
  m_colour = data.m_colour;
  m_headerMargin = data.m_headerMargin;
  m_footerMargin = data.m_footerMargin;
  m_showOnFirstPage = data.m_showOnFirstPage;
}

void wxRichTextHeaderFooterData::SetText( const wxString& text, int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location ) {
  int idx = headerFooter + ( 2 * ( int ) page ) + ( 4 * ( int ) location );
  wxASSERT( idx >= 0 && idx < 12 );
  if( idx >= 0 && idx < 12 ) {
    m_text[idx] = text;
  }
}

wxString wxRichTextHeaderFooterData::GetText( int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location ) const {
  int idx = headerFooter + ( 2 * ( int ) page ) + ( 4 * ( int ) location );
  wxASSERT( idx >= 0 && idx < 12 );
  if( idx >= 0 && idx < 12 ) {
    return m_text[idx];
  } else
  { return wxEmptyString; }
}

void wxRichTextHeaderFooterData::SetHeaderText( const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location ) {
  if( page == wxRICHTEXT_PAGE_ALL ) {
    SetText( text, 0, wxRICHTEXT_PAGE_ODD, location );
    SetText( text, 0, wxRICHTEXT_PAGE_EVEN, location );
  } else
  { SetText( text, 0, page, location ); }
}

wxString wxRichTextHeaderFooterData::GetHeaderText( wxRichTextOddEvenPage page, wxRichTextPageLocation location ) const {
  return GetText( 0, page, location );
}

void wxRichTextHeaderFooterData::SetFooterText( const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location ) {
  if( page == wxRICHTEXT_PAGE_ALL ) {
    SetText( text, 1, wxRICHTEXT_PAGE_ODD, location );
    SetText( text, 1, wxRICHTEXT_PAGE_EVEN, location );
  } else
  { SetText( text, 1, page, location ); }
}

wxString wxRichTextHeaderFooterData::GetFooterText( wxRichTextOddEvenPage page, wxRichTextPageLocation location ) const {
  return GetText( 1, page, location );
}

/// Clear all text
void wxRichTextHeaderFooterData::Clear() {
  int i;
  for( i = 0; i < 12; i++ ) {
    m_text[i] = wxEmptyString;
  }
}
